import type { Token } from '@/types/retrieval-sql'

export default function tokenizer(input: string) {
  // 记录当前解析到词的位置
  let current = 0
  // tokens 用来保存我们解析的 token
  const tokens: Token[] = []

  // 利用循环进行解析
  while (current < input.length) {
    // 提取出当前要解析的字符
    let char = input[current]
    const start = current

    // 处理符号: 检查是否是符号
    const PUNCTUATOR = /[()=<>（）]/im
    if (PUNCTUATOR.test(char)) {
      // 创建变量用于保存匹配的符号
      current++
      const map: Record<string, string> = {
        '（': '(',
        '）': ')',
      }

      // 最后把数据更新到 tokens 中
      tokens.push({
        type: 'Punctuator',
        value: map[char] ?? char,
        start,
        end: current,
      })
      // 进入下一次循环
      continue
    }

    // 处理空格: 如果是空格
    const WHITESPACE = /\s/
    if (WHITESPACE.test(char)) {
      const start = current
      while (current < input.length && WHITESPACE.test(char)) {
        char = input[++current]
      }
      tokens.push({
        type: 'Whitespace',
        value: '',
        start,
        end: current,
      })
      continue
    }

    // 匹配形双引号包围的字符串“”
    if (/["“]/.test(char)) {
      const punctuator = (char === '"' ? '"' : '”')
      let value = ''
      char = input[++current] // 跳过左双引号

      // 获取两个双引号之间所有字符
      while (current < input.length && char !== punctuator) {
        value += char
        char = input[++current]
      }

      tokens.push({
        type: 'Identifier', value, start, end: current,
      })
      char = input[++current]// 跳过右双引号
      continue
    }

    // 处理字符
    let value = ''
    while (char !== undefined && !WHITESPACE.test(char) && !PUNCTUATOR.test(char)) {
      value += char
      char = input[++current]
    }

    const KEYWORD = /^(AND|OR|NOT)$/i
    if (KEYWORD.test(value)) {
      // 标记关键字
      tokens.push({
        type: 'Keyword',
        value: value.toUpperCase(),
        start,
        end: current,
      })
    } else {
      // 标记变量
      tokens.push({
        type: 'Identifier',
        value,
        start,
        end: current,
      })
    }
  }
  // 词法分析器的最后我们返回 tokens 数组。
  return tokens
}
